xen/arm: gic-v2: Automatically detect aliased GIC400
authorJulien Grall <julien.grall@citrix.com>
Thu, 8 Oct 2015 18:23:53 +0000 (19:23 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 23 Oct 2015 13:28:09 +0000 (14:28 +0100)
commit21550029f709072aacf3b90edd574e7d3021b400
treec513a3abae5c2aaae30375dca3af1614fa2e2fbc
parent61edf8a6f837b45572704aceca7c71d67858c062
xen/arm: gic-v2: Automatically detect aliased GIC400

We are currently using a per-platform quirk to know if the 2 4KB region of
the GIC CPU interface are each aligned to 64KB. Although, it may be
possible to have different layout on a same platform (depending on the
firmware version).

Rather than having a quirk it's possible to detect by reading the GIC
memory. This patch is based from the Linux commit "irqchip/GIC: Add workaround
for aliased GIC400" [1].

Take the opportunity to clean up the GICv2 of code which was only
required because of the quirk.

Note that none of the platform using the gic-hip04 were actually using
the quirk, so the code has been dropped. I will let the maintainers
decide whether it's relevant or not to add proper detection for aliased
GIC for this hardware.

[1] commit 12e14066f4835f5ee1ca795f0309415b54c067a9
    Author: Marc Zyngier <marc.zyngier@arm.com>
    Date:   Sun Sep 13 12:14:31 2015 +0100

    irqchip/GIC: Add workaround for aliased GIC400

    The GICv2 architecture mandates that the two 4kB GIC regions are
    contiguous, and on two separate physical pages (so that access to
    the second page can be trapped by a hypervisor). This doesn't work
    very well when PAGE_SIZE is 64kB.

    A relatively common hack^Wway to work around this is to alias each
    4kB region over its own 64kB page. Of course in this case, the base
    address you want to use is not really the begining of the region,
    but base + 60kB (so that you get a contiguous 8kB region over two
    distinct pages).

    Normally, this would be described in DT with a new property, but
    some HW is already out there, and the firmware makes sure that
    it will override whatever you put in the GIC node. Duh. And of course,
    said firmware source code is not available, despite being based
    on u-boot.

    The workaround is to detect the case where the CPU interface size
    is set to 128kB, and verify the aliasing by checking that the ID
    register for GIC400 (which is the only GIC wired this way so far)
    is the same at base and base + 0xF000. In this case, we update
    the GIC base address and let it roll.

    And if you feel slightly sick by looking at this, rest assured that
    I do too...

Reported-by: Julien Grall <julien.grall@citrix.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Stuart Yoder <stuart.yoder@freescale.com>
Cc: Pavel Fedin <p.fedin@samsung.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Link: http://lkml.kernel.org/r/1442142873-20213-2-git-send-email-marc.zyngier@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/gic-hip04.c
xen/arch/arm/gic-v2.c
xen/arch/arm/gic-v3.c
xen/arch/arm/platforms/xgene-storm.c
xen/arch/arm/vgic-v2.c
xen/include/asm-arm/gic.h
xen/include/asm-arm/platform.h
xen/include/asm-arm/vgic.h